package net.csdn.business.auth.controller;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.csdn.business.common.domain.request.oauth.StatClientAuthQuery;
import net.csdn.business.common.domain.vo.UserVo;
import net.csdn.business.common.oauth2.service.IOauthAccessTokenService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.exceptions.InvalidRequestException;
import org.springframework.security.oauth2.provider.AuthorizationRequest;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.RedirectView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.security.Principal;
import java.util.Map;


/**
 * @Desc: Tokencontroller
 * @ClassName: TokenController
 * @Author: yourleige@163.com
 * @Date: 2022/9/27 11:16
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/oauth")
public class TokenController
{

    private final ClientDetailsService clientDetailsService;

    private final AuthorizationEndpoint authorizationEndpoint;

    private final IOauthAccessTokenService oauthAccessTokenService;


    @Value("${oauth.host:http://www.baidu.com}")
    private String host;

    @Value("${oauth.login.route:/test}")
    private String loginPageRoute;

    @Value("${oauth.confirm.route:/confirm}")
    private String confirmPageRoute;



    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    /**
     * 跳转到登录页面
     * @return ModelAndView
     */
    @GetMapping("/login")
    public String login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String targetUrl=host+loginPageRoute;
        log.info("跳转登录页面目标页面为：{}",targetUrl);
        redirectStrategy.sendRedirect(request, response, targetUrl);
        return "redirect";
    }

    /**
     * 确认授权页面
     * @param request
     * @return
     */
    @GetMapping("/confirm")
    public String confirm(HttpServletRequest request,HttpServletResponse response,HttpSession session) throws IOException {
        String clientId=null;
        Object auth = session.getAttribute("authorizationRequest");
        if (auth != null) {
            AuthorizationRequest authorizationRequest = (AuthorizationRequest) auth;
            ClientDetails clientDetails = clientDetailsService.loadClientByClientId(authorizationRequest.getClientId());
            clientId=clientDetails.getClientId();
        }
        String targetUrl=host+confirmPageRoute+clientId;
        log.info("跳转授权页面目标页面为：{}",targetUrl);
        redirectStrategy.sendRedirect(request, response, targetUrl);
        return "redirect";
    }

    /**
     * 提交授权接口，返回授权码和跳转链接
     * @param approvalParameters
     * @return
     */
    @RequestMapping(
            value = {"/approveOrDeny"},
            method = {RequestMethod.POST,RequestMethod.GET},
            params = {"user_oauth_approval"}
    )
    public View approveOrDeny(@RequestParam Map<String, String> approvalParameters, Map<String, Object> model, SessionStatus sessionStatus, Principal principal,HttpSession session){
        Object auth = session.getAttribute("authorizationRequest");
        String userName=null;
        Authentication token=(Authentication)principal;
        if(token!=null){
            userName=token.getName();
            //根据userName获取用户是否已经验证邮箱
            UserVo userVo=null;
            //UserVo userVo=userFeignClient.getUserByUserName(userName,null);
            log.info("确认授权-获取用户信息：{}", JSON.toJSONString(userVo));
            if(userVo!=null&&(!userVo.getEmailVerified()||!userVo.getPhoneVerified())){
                throw new InvalidRequestException("Email and Phone must to be verified");
            }
        }
        if(auth!=null){
            model.put("authorizationRequest",auth);
            AuthorizationRequest authorizationRequest=(AuthorizationRequest)auth;
            //异步更新授权统计数量
            StatClientAuthQuery query=new StatClientAuthQuery();
            query.setClientId(authorizationRequest.getClientId());
            query.setUserName(userName);
            query.setStatDate(DateUtil.today());
            oauthAccessTokenService.statClientAuth(query);
        }
        Object originalAuthor = session.getAttribute("org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.ORIGINAL_AUTHORIZATION_REQUEST");
        if(originalAuthor!=null){
            model.put("org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.ORIGINAL_AUTHORIZATION_REQUEST",originalAuthor);
        }
        RedirectView result= (RedirectView)authorizationEndpoint.approveOrDeny(approvalParameters,model,sessionStatus,principal);
        return result;
    }

}
